package com.google.code.jholidays.events;

import com.google.code.jholidays.core.EventDescriptor;
import com.google.code.jholidays.events.properties.AbstractEventProperties;
import com.google.code.jholidays.events.properties.IEventProperties;

/**
 * Provides skeletal implementation of {@link IEvent} interface
 * <p>
 * Each subclass should provide only protected constructor(s). To create
 * instance of concrete implementation of {@link IEvent} concrete implementation
 * of {@link IFactory} should be used: <code>
 * <pre>
 * IFactory factory = new ConcreteFactory()
 * IEvent event = 
 * 	factory.createEvent(descriptor, parentEvent);</pre>
 * </code>
 * 
 * @author tillias
 * @see IEventProperties
 * @see AbstractEventProperties
 * @see IFactory
 * 
 */
public abstract class AbstractEvent implements IEvent {

    /**
     * Sole constructor for subclasses invocation
     * 
     * @param properties
     *            Event properties
     * @exception IllegalArgumentException
     *                Thrown if properties parameter passed to constructor is
     *                null
     */
    protected AbstractEvent(IEventProperties properties)
	    throws IllegalArgumentException {
	if (properties == null)
	    throw new IllegalArgumentException("Properties is null");

	this.properties = properties;
    }

    /**
     * Gets value indicating whether current event is root one (e.g. has no
     * parent events)
     * 
     * @return True if current event has no parent one, false otherwise
     */
    public boolean isRoot() {
	return getParent() == null;
    }

    /**
     * Gets event expression
     * 
     * @return Event expression
     */
    public String getExpression() {
	return getDescriptor().getExpression();
    }

    @Override
    public int getID() {
	return getDescriptor().getID();
    }

    @Override
    public String getName() {
	return getDescriptor().getName();
    }

    @Override
    public String getDescription() {
	return getDescriptor().getDescription();
    }

    @Override
    public EventDescriptor getDescriptor() {
	return getProperties().getDescriptor();
    }

    /**
     * Gets current event's parent
     * 
     * @return Event's parent if it is dependent event, null otherwise
     * @see #isRoot()
     */
    public IEvent getParent() {
	return getProperties().getParent();
    }

    /**
     * Returns {@link IEventProperties} associated with given event
     * 
     * @return Event properties
     */
    protected IEventProperties getProperties() {
	return properties;
    }

    IEventProperties properties;
}
